package gaml.yaml.ahchor;

import gaml.error.GamlException;
import gaml.yaml.YamlNode;

import java.util.HashMap;


/**
 * avoid ciclic references and repeat object
 * serializations by indexing objects with unique anchors
 * @author shnireck
 *
 */
public class YamlAnchorObjectStore {
	HashMap <Object, YamlAnchor> anchors = new HashMap <Object, YamlAnchor> ();
	int count = 0;
	
	/**
	 * see if serializing object already
	 * been serialized
	 * @param object serializing object
	 * @return true if object already serialized in this session
	 * and should only be referenced by anchor
	 * @throws GamlException 
	 */
	public boolean checkRepeat (Object object, YamlNode node) throws GamlException {
		if (null != node.getAnchor ()) return false;
		if (! (anchors.containsKey (object))) { 
			anchors.put (object, node.setAnchor (new YamlAnchor (getNewCode (), object, node)).getAnchor ());
			return false;
		}

		return true;
	}
	
	/**
	 * get anchor for specified object
	 * @param object java object, whose anchor we are looking for
	 * @return anchor for object, null if no anchors for specified object exists
	 */
	public YamlAnchor getAnchor (Object object) { return anchors.get (object); }
	
	/**
	 * remove unused anchors from collection
	 * @return host anchors collection object
	 */
	public YamlAnchorObjectStore shrinkAnchors () {
		for (YamlAnchor anchor: anchors.values ())
			if (! anchor.isUsed())
				anchor.getNode().setAnchor (null);
		
		return this;
	}
	
	/**
	 * adding new anchor for serialized object to store
	 * @param object java object, on wich this anchor referers
	 * @param anchor new anchor for new object
	 * @return host store object
	 */
//	public YamlAnchorObjectStore putAnchor (Object object, YamlAnchor anchor) { anchors.put (object, anchor); return this; }
	 
	protected String getNewCode () { return String.format ("%016d", count++); }
}
